init('ItemService');
(function(){
	var Collections = require('Collections'),
        ObjectUtils = require('ObjectUtils'),
        AutoCompleteResponse = require('AutoCompleteResponse').ctor;

	var Map     = Collections.Map,
	    List    = Collections.List,
	    iterate = Collections.iterate;
	
	var merge   = ObjectUtils.merge,
	    propertyAccessor = ObjectUtils.propertyAccessor;
	
	namespace('org.jsmud');
	
	org.jsmud.ItemService = function(db){
		this.db = db;
	};
	org.jsmud.ItemService.prototype = {
		_toEntity : function(obj){
			return new org.jsmud.entity.Item(this, obj);
		},
		_convertResults : function(results){
			var service = this;
			var toEntity = function(obj){ return service._toEntity(obj); }
			if( results ) 
				return List.addAll([], results, toEntity);
		},
		findById : function(id, onLoad){
			var scope = this;
			var onSuccess = function(obj){
				if( obj.results.length == 1 ){
					if( onLoad ) onLoad(scope._toEntity(obj[0]));
				}else{
					console.log("Failed to load item : " + id);
				}
			};
			var onError = function(err){
				if( onLoad ) onLoad(null);
			}
			this.db.findById(id, onSuccess, onError);
		},
		findByExample : function(example, onLoad){
			var service = this;
			var onSuccess = function(obj){
				if( onLoad ) onLoad(service._convertResults(obj));
			};
			var onError = function(err){
				if( onLoad ) onLoad(null);
			};
			this.db.find({example:example}, onSuccess, onError);
		},
		list : function(onLoad){
			var db = this.db;
			var service = this;
			var onSuccess = function(obj){
				if( onLoad ) onLoad(service._convertResults(obj));
			};
			var onError = function(err){
				if( onLoad ) onLoad(null);
			};
			db.find({}, onSuccess, onError);
		},
		save : function(obj, onSuccess, onError){
			this.db.save(obj, onSuccess, onError);
		},
		commands : {
			create : {
				onExecute : function(itemName, collectionName, _id, position){
					var col = this.session[collectionName];
					if( !col ){
						_id = this.session.room.getId();
						collectionName = 'room';
					}
					if( !_id ){
						_id = col.data._id;
					}
					var data = {
						name : itemName
						,container : {
							collectionName : collectionName
							,_id : _id
							,position : position ? position : null
						}
					}
					var item = new org.jsmud.entity.Item(this.owner, data);
					item.save();
				}
			},
			look : {
				onExecute : function(){
					var item = arguments.length > 1 ? arguments[1] : null;
					var user = this.session.getUser();
					var room = this.session.getRoom();
					var onResponse = this.onResponse;
					var itemService = this.owner;
					if( arguments[0] == 'in' ){
						var example = {$or:
							[{name:item, 'container.collectionName':'user', 'container.position':'carryables', 'container._id':user.getId()}
							,{name:item, 'container.collectionName':'user', 'container.position':'wearables', 'container._id':user.getId()}
							,{name:item, 'container.collectionName':'room', 'container._id':room.getId()}
						]};
						itemService.findByExample(example, function(results){
							if(!results || results.length != 1 ){
								onResponse('Object not found: ' + item);
								return;
							}
							var id = results[0].getId();
							itemService.findByExample({'container.collectionName':'item', 'container._id':id}, function(options){
								if(options && options.length){
									onResponse(new AutoCompleteResponse('', [{values:options, toHTML:'${data.name} ', _toString:propertyAccessor('data.name')}]));
								}else{
									onResponse(_('Nothing in ${0}.', item));
								}
								
							});
						});
					}else if( arguments[0] == 'at' ){
						
					}else{
						this.commandService.execute('describe', onResponse);
					}
				}
			}
		},
		getCommands : function(onResponse){
			var results = {};
			Map.putAll(results, this.commands, merge({owner:this}).mapEntry);
			onResponse(results);
		}
	};
})();